#include "CUserPet.h"
#include "../mainctrl.h"
#include "commmsg.h"
#include <algorithm>
//#include "CTTime.h"
#include "MsgComm.pb.h"

void CUserPet::Clean()
{
    CT_TRACE(("清理 UserPet"));
    
    m_petData.Clear();
    m_bPetStatusChange = false;
}


int CUserPet::PetIsActive()
{
    return this->m_petData._iIsActive;
}

/*
int CUserPet::UpdateTaskStatus()
{
    if( this->m_bTaskTargetStatus )
    {
        //检查待激活任务是否可以转变为激活任务，如果可以，将任务激活
        int iRet = CheckWaitForOpenTask();
        CHECK_RETURN(iRet);

        iRet = CheckValidTask();
        CHECK_RETURN(iRet);

        int iIndex = CMainCtrl::m_pstMain->m_stPlayerBaseInfoHash.HashFind(this->GetUserGid());
        if (iIndex < 0)
        {
            CT_ERROR(("user %u not in hash", this->GetUserGid()));
            return -1;
        }
        CPlayerBaseInfo& stPlayerBaseInfo = CMainCtrl::m_pstMain->m_stPlayerBaseInfoHash[iIndex];

        iRet = this->GetData( stPlayerBaseInfo._stUserTaskData);
        CHECK_RETURN(iRet);

        //保存数据
        CVarObjectKey stKey;
        stKey.m_chDataType = DT_PLAYER_BASE_INFO;
        stKey.m_u64ID = stPlayerBaseInfo._uiGID;
        CMainCtrl::m_pstMain->UpdateData(stKey, stPlayerBaseInfo, VOP_UPDATE);

        //下发任务数据
        iRet = UpdateTaskList2Front();
        CHECK_RETURN(iRet);
    }

    this->m_bTaskTargetStatus = false;

    return 0;
}

int CUserPet::UpdateTaskList2Front()
{
    int iRet = 0;

    CCmdGetTaskList NewCmdTaskList; 
    NewCmdTaskList.pstMainCtrl = CMainCtrl::m_pstMain;
    iRet = CMainCtrl::m_pstMain->m_stPlayerOnline.GetOnlinePlayerHandle(this->GetUserGid(), NewCmdTaskList.stEnpHead);
    CHECK_RETURN(iRet);

    NewCmdTaskList.uiGID = this->GetUserGid();

    // set msg head common part
    NewCmdTaskList.stMsgHead.set_version(1000);
    NewCmdTaskList.stMsgHead.set_time((int)time(NULL));
    NewCmdTaskList.stMsgHead.set_msgact(0);
    NewCmdTaskList.stMsgHead.set_msgid(ID_MAIN_GET_TASK_LIST);
    //NewCmdTaskList.stMsgHead.set_msgtype(CSMsgDef::EMT_REQUEST);
    NewCmdTaskList.stMsgHead.set_msgret(0);

    iRet = NewCmdTaskList.LogicDo(RET_OK);

    return iRet;
}
*/

/*
CAREER_1 = 1,       //魔剑士 sword
CAREER_2 = 2,       //魔法师 mage
CAREER_3 = 3,       //魔猎手 bow
CAREER_4 = 4,       //魔斗士 awl
魔法师获得魔攻宠物猫头鹰，魔剑士和魔猎手获得物攻宠物仓鼠
*/
int CUserPet::Init(unsigned char _ucCareer)
{
    int iRet = 0;

    if( this->PetIsActive() )
    {
        return ERROR_PET_ALREADY_INIT;//已经初始化过
    }

    //缺省都是猫头鹰
    this->m_petData._iPetStyle = PET_STATUS_TYPE_OWL;
    this->m_petData._iPetMaxCanUseStyle = PET_STATUS_TYPE_OWL; //只能用猫头鹰

    this->m_petData._iIsActive = 1; //设置为激活宠物
    this->m_petData._iPetLevel = 1;
    this->m_petData._iPetStar  = 0;
    this->m_petData._iPetExper = 0;
    //this->m_petData._iCurTime  = this->ConsumeDayFlag();
    this->m_petData._iNextCDTime = 0;
    //this->m_petData._iExploreCountInDay = MAX_PET_EXPLORE_NUM;
    this->m_petData._sExploreCountInDay._stData = MAX_PET_EXPLORE_NUM;
    this->m_petData._sExploreCountInDay._iLastUpdateTime = CMainCtrl::m_pstMain->m_iNow;
    this->m_petData._iPetFruit   = 0;
    this->m_petData._iDailyCritNums = MAX_DAILY_CRIT_NUM;
    this->m_petData._sPetName.Set(DEFAULT_PET_NAME);
    this->m_petData._iIsRecvFruit = CONST_PET_NOT_FRUIT_RECV;
    this->m_petData._aPetAwardFruits.Clear();

    iRet = ShuffleExploreEventList();
    CHECK_RETURN(iRet);

    m_bPetStatusChange = true;

    //更新
    this->UpdatePetStatus();

    return iRet;
}

//取得宠物等阶
int CUserPet::GetPetLevel()
{
    return this->m_petData._iPetLevel;
}

//取得宠物星级
int CUserPet::GetPetStar()
{
    return this->m_petData._iPetStar;
}

//生成值[iMin, iMax)
int CUserPet::GetRandomRange(int iMin, int iMax)
{
    int iResult = 0;

    while(true)
    {
        iResult = random()%(iMax-iMin) + iMin;
        if( iResult>=iMin && iResult<iMax ) break;
    }

    return iResult;
}

int CUserPet::ShuffleExploreEventList()
{
    ExploreRandArray& aiExploreConfigEventRand = CMainCtrl::m_pstMain->m_stPetMgr.GetExploreRandArray();
    int iMaxExploreCounts = aiExploreConfigEventRand.Size();
    if( iMaxExploreCounts<MAX_PET_EXPLORE_NUM )
    {
        return ERROR_PET_EXPLORE_COUNTS_CONFIG;
    }

    aiExploreConfigEventRand.Random();

    this->m_petData._aPetExploreEventList.Clear();

    for( int i=0; i<MAX_PET_EXPLORE_NUM; ++i )
    {
        this->m_petData._aPetExploreEventList.AddOneItem(aiExploreConfigEventRand[i]);
    }

    return 0;
}

/*
int CUserPet::ShuffleExploreEventList()
{
    int iMaxExploreCounts = CMainCtrl::m_pstMain->m_stPetMgr.GetPetExploreConfigCounts();
    if( iMaxExploreCounts<MAX_PET_EXPLORE_NUM )
    {
        return ERROR_PET_EXPLORE_COUNTS_CONFIG;
    }

    int iMin = 1;
    int iMax = iMaxExploreCounts+1;
    int iRandomEventId = 0;
    bool bHasRepeat = false;
    this->m_petData._aPetExploreEventList.Clear();

    for( int i=0; i<MAX_PET_EXPLORE_NUM; )
    {
        iRandomEventId = GetRandomRange(iMin, iMax);
        bHasRepeat = false; 
        for( int j=0; j<this->m_petData._aPetExploreEventList.Size(); ++j )
        {
            if( this->m_petData._aPetExploreEventList[j]==iRandomEventId )
            {//重复
                bHasRepeat = true;
                break;
            }
        }

        if( !bHasRepeat )
        {
            this->m_petData._aPetExploreEventList.AddOneItem(iRandomEventId);
            ++i;
        }
    }

    return 0;
}
*/


int CUserPet::InitData(CPetData& stUserData)
{
    int iRet = 0;
    Clean();

    this->m_petData = stUserData;

    //利用已经存在的初始化数据
    /*for( int i=0; i<this->m_petData._aPetExploreEventList.Size(); ++i )
    {
        this->_vPetExploreEventList.push_back( m_petData._aPetExploreEventList[i] );
    }*/

    return iRet;
}


int CUserPet::GetData(CPetData& stUserPetData)
{
    int iRet = 0;
    stUserPetData.Clear();

    stUserPetData = this->m_petData;

    return iRet;
}

CPetData& CUserPet::GetDataRef()
{
    return this->m_petData;
}

//同一天必须相同,比较年，月，日即可
int CUserPet::ConsumeDayFlag()
{
    int iConsumeDayFlag = 0;
    time_t tCur = CMainCtrl::m_pstMain->m_iNow;
    CTTime  ctCur(tCur);

    int iYear = ctCur.GetYear();
    int iMonth = ctCur.GetMonth();
    int iDay = ctCur.GetDay();

    iConsumeDayFlag = iYear*10000 + iMonth*100 + iDay;

    return iConsumeDayFlag;
}

void CUserPet::PetExplore(int iCDTimes)
{
    //this->m_petData._iExploreCountInDay -= 1;
    this->m_petData._sExploreCountInDay.Sub( 1, CMainCtrl::m_pstMain->m_iNow );
    //设置下次探险冷却cd时间
    int iNextCDTimeConfig = iCDTimes; //暂定60s，需要改成从配置文件读取
    this->m_petData._iNextCDTime = CMainCtrl::m_pstMain->m_iNow + iNextCDTimeConfig; 

    m_bPetStatusChange = true;
    //更新
    this->UpdatePetStatus();
}

int CUserPet::CheckCDTime()
{
    return this->m_petData._iNextCDTime;
}

//吃一个增益果实
void CUserPet::PetTrainFruit()
{
    this->m_petData._iPetFruit += 1;

    m_bPetStatusChange = true;
    //更新
    this->UpdatePetStatus();
}

//获得宠物经验
void CUserPet::TriggerIncrExper(int iExperValue)
{
    this->m_petData._iPetExper += iExperValue;

    m_bPetStatusChange = true;
    //更新
    this->UpdatePetStatus();
}

//大暴击直接提升星级
void CUserPet::TriggerBigCrit()
{
    this->m_petData._iPetStar += 1;

    m_bPetStatusChange = true;
    //更新
    this->UpdatePetStatus();
}

int CUserPet::GetExploreAwardItemsWithLevel(short iLevel, CPetExploreConfigData& stConfigData, CDropItem& stDropItem)
{
    int iRet = 0;
    CDropItemData stDropItemData;

    for (int i = 0; i < stConfigData._aTExploreAwards.Size(); ++i)
    {//此处不考虑类集的物品奖励
        const CPetExploreConfigData::TExploreAward& OneExploreAward = stConfigData._aTExploreAwards[i];

        iRet = CMainCtrl::m_pstMain->m_stItemMgr.GetDropItemData(GetUserGid(), OneExploreAward.iAwardItemType, 
                    OneExploreAward.iAwardItemId, "", COMM_MOD, OneExploreAward.iAwardNum, stDropItemData);
        CHECK_RETURN(iRet);

        stDropItem.Drop(stDropItemData);
    }
    return iRet;
}


int CUserPet::GetExploreAwardItems(CPetExploreConfigData& stConfigData, CDropItem& stDropItem)
{
    int iRet = 0;
    CDropItemData stDropItemData;

    for (int i = 0; i < stConfigData._aTExploreAwards.Size(); ++i)
    {//此处不考虑类集的物品奖励
        const CPetExploreConfigData::TExploreAward& OneExploreAward = stConfigData._aTExploreAwards[i];
        CMainCtrl::m_pstMain->m_stItemMgr.GetDropItemData(GetUserGid(), OneExploreAward.iAwardItemType, 
                    OneExploreAward.iAwardItemId, "", COMM_MOD, OneExploreAward.iAwardNum, stDropItemData);

        stDropItem.Drop(stDropItemData);
    }
    return iRet;
}

int CUserPet::PetRename(CTSizeString<PETNAME_LEN>& szPetName)
{
    this->m_petData._sPetName = szPetName;

    m_bPetStatusChange = true;
    //更新
    this->UpdatePetStatus();

    return 0;
}

//查询剩余探险次数
int CUserPet::GetPetExploreCounts()
{
    int iRet = 0;
    //查看是否在当天的
    //int iTmpCurTime = this->ConsumeDayFlag();
    //if( iTmpCurTime != this->m_petData._iCurTime )
    if( !this->m_petData._sExploreCountInDay.IsSameDay(CMainCtrl::m_pstMain->m_iNow) )
    {
        //this->m_petData._iCurTime = iTmpCurTime; 
        this->m_petData._iNextCDTime = 0; 
        //this->m_petData._iExploreCountInDay = MAX_PET_EXPLORE_NUM;
        this->m_petData._iDailyCritNums = MAX_DAILY_CRIT_NUM;
        //重新生成随机探险事件id列表
        iRet = ShuffleExploreEventList();
        CHECK_RETURN(iRet);
    
        this->m_petData._sExploreCountInDay._stData = MAX_PET_EXPLORE_NUM;
        this->m_petData._sExploreCountInDay._iLastUpdateTime = CMainCtrl::m_pstMain->m_iNow;

        m_bPetStatusChange = true;
    }

    //更新
    this->UpdatePetStatus();

    //return this->m_petData._iExploreCountInDay;
    return this->m_petData._sExploreCountInDay.Get( CMainCtrl::m_pstMain->m_iNow );
}

int CUserPet::GetPetExploreId(int iRemainCounts)
{
    if( iRemainCounts<1 || iRemainCounts>this->m_petData._aPetExploreEventList.Size() )
    {
        return ERROR_PET_EXPLORE_ID;
    }
    return this->m_petData._aPetExploreEventList[iRemainCounts-1];
}

void CUserPet::TriggerCritNumDesc()
{
    this->m_petData._iDailyCritNums -= 1;

    //暴击次数减少不需要更新到前端
/* 
 *  m_bPetStatusChange = true;
    //更新
    this->UpdatePetStatus();
*/
}

int CUserPet::GetCurPetExper()
{
    return this->m_petData._iPetExper;
}

int CUserPet::PetRecvFruit()
{
    int iRet = 0;

    //设置有果实没有领取标志?
    if( this->m_petData._iIsRecvFruit != CONST_PET_HAS_FRUIT_NOT_RECV )
    {
        return ERROR_NOT_FRUIT_RECV;
    }

    //发放奖励果实给用户
    iRet = PetSendFruit2Storage();
    CHECK_RETURN( iRet );
    //
    //设置没有果实领取标志, 果实数组清空
    this->m_petData._iIsRecvFruit =  CONST_PET_NOT_FRUIT_RECV;
    this->m_petData._aPetAwardFruits.Clear();

    m_bPetStatusChange = true;

    //更新
    this->UpdatePetStatus();

    return iRet;

}


int CUserPet::PetSendFruit2Storage()
{
    int iRet = 0;
    CDropItem  stDropItem;

    for( int i=0; i<this->m_petData._aPetAwardFruits.Size(); ++i )
    {
        CDropItemData stDropItemData;
        short iFruitId = this->m_petData._aPetAwardFruits[i];

        CFruitUnitConfig stConfigData;
        iRet = CMainCtrl::m_pstMain->m_stItemMgr.GetFruitConfig( iFruitId, stConfigData );
        if( iRet!=RET_OK )
        {
            CT_ERROR(("error pet fruit  id %d.", iFruitId));
            continue;
        }
 
        //stDropItemData._ucItemType = ITEM_TYPE_FRUIT;
        //stDropItemData._usItemConfigID = iFruitId;
        //stDropItemData._iItemCount = 1;
        //stDropItem._astDropItem.AddOneItem( stDropItemData );

        CMainCtrl::m_pstMain->m_stItemMgr.GetDropItemData(_uiGID, ITEM_TYPE_FRUIT, iFruitId, "", COMM_MOD, 1, stDropItemData);
        stDropItem.Drop(stDropItemData);
    }

    stDropItem.SetOssModule(OSS_MODULE_PET);
    iRet = CMainCtrl::m_pstMain->m_stItemMgr.DropItem(NULL, _uiGID, stDropItem);

    return iRet;
}

//有前端主动请求升等阶
int CUserPet::PetReqUpdateLevel()
{
    int iRet = 0;

    if( this->m_petData._iPetStar >= MAX_PET_STAR )//等阶升级
    {
        if( this->m_petData._iPetLevel < MAX_PET_LEVEL_CONFIG )//是否达到最大等阶
        {
            this->m_petData._iPetLevel += 1;
            this->m_petData._iPetStar -= MAX_PET_STAR;
            iRet = RET_OK;

            m_bPetStatusChange = true;
        }
        else
        {
            return ERROR_PET_LEVEL_MAX;
        }
    }
    else
    {
        return ERROR_PET_UPDATE_LEVEL_NOT_ENOUGH_STAR;
    }

    //更新
    this->UpdatePetStatus();

    return iRet;

}

void CUserPet::SetPetInfoBatch( int & iLevel, int & iStar, int & iCurExper, FruitAwardArray & aAwardFruits )
{
    this->m_petData._iPetExper = iCurExper;
    this->m_petData._iPetLevel = iLevel;
    this->m_petData._iPetStar  = iStar;

    for( int i=0; i<aAwardFruits.Size(); ++i )
    {
        this->m_petData._aPetAwardFruits.AddOneItem( aAwardFruits[i] );
        //设置有果实没有领取标志
        this->m_petData._iIsRecvFruit = CONST_PET_HAS_FRUIT_NOT_RECV;
    }

    m_bPetStatusChange = true;
}

int CUserPet::GetPetExper()
{
    return this->m_petData._iPetExper;
}

/*
 * Return: 0:sucess
 *         1:宠物等阶升级了，petMgr收到此信息需要做全服广播
 *         other: error
 * */
//int CUserPet::CheckPetUpdate(CPetStarConfigData& stData)
int CUserPet::CheckPetUpdate()
{
    int iRet = 0;
    CPetStarConfigData stData;
    int iPetFruit = 0;
    int iPetNextFruit = 0;

    int iCurExper = this->GetCurPetExper();
    CMainCtrl::m_pstMain->m_stPetMgr.GetPetStarConfig( *this, stData );
    //CHECK_RETURN(iRet);

    while( iCurExper>0 && iCurExper>=stData._iNeedExp )//星级升级
    {
        this->m_petData._iPetStar += 1;
        this->m_petData._iPetExper = iCurExper - stData._iNeedExp;

        //检查是否达到最大等阶
        if( this->m_petData._iPetLevel>=MAX_PET_LEVEL_CONFIG && this->m_petData._iPetStar>=MAX_PET_STAR-1 )
        {
            this->m_petData._iPetLevel = MAX_PET_LEVEL_CONFIG;
            this->m_petData._iPetStar = MAX_PET_STAR-1;
            iCurExper = 0;
        }

        //检查是否发放果实，13579星级可以奖励果实，当前星级和下一果实星级的两个果实
        if( this->m_petData._iPetStar==1 || this->m_petData._iPetStar==3 ||
            this->m_petData._iPetStar==5 || this->m_petData._iPetStar==7 ||
            this->m_petData._iPetStar==9 )
        {
            //设置有果实没有领取标志
            this->m_petData._iIsRecvFruit = CONST_PET_HAS_FRUIT_NOT_RECV;
            //放置奖励果实给前台
            iPetFruit = MAX_PET_LEVEL_CONFIG * this->m_petData._iPetLevel + this->m_petData._iPetStar;
            this->m_petData._aPetAwardFruits.AddOneItem( iPetFruit );

            //检查是否达到最大等阶
            if( !(this->m_petData._iPetLevel>=MAX_PET_LEVEL_CONFIG && this->m_petData._iPetStar>=MAX_PET_STAR-1) )
            {

                iPetNextFruit = iPetFruit + 2;
                if( iPetNextFruit<MAX_PET_LEVEL_CONFIG * MAX_PET_LEVEL_CONFIG + MAX_PET_STAR )
                {
                    this->m_petData._aPetAwardFruits.AddOneItem( iPetNextFruit );
                }
            }
        }
        m_bPetStatusChange = true;

        //检查是否达到最大等阶
        if( this->m_petData._iPetStar>=MAX_PET_STAR )
        {
            break;
        }

        iCurExper = this->GetCurPetExper();
        iRet = CMainCtrl::m_pstMain->m_stPetMgr.GetPetStarConfig( *this, stData );
        CHECK_RETURN(iRet);
    }

/*
 * 现在升级等阶需要前端主动发起请求才能升阶
    if( this->m_petData._iPetStar >= MAX_PET_STAR )//等阶升级
    {
        if( this->m_petData._iPetLevel < MAX_PET_LEVEL_CONFIG )//是否达到最大等阶
        {
            this->m_petData._iPetLevel += 1;
            this->m_petData._iPetStar -= MAX_PET_STAR;
            iRet = 1;

            m_bPetStatusChange = true;
        }
        else
        {
            return ERROR_PET_LEVEL_MAX;
        }
    }
*/

    //更新
    this->UpdatePetStatus();

    return iRet;
}

//清除cd时间
int CUserPet::PetClearCDTime()
{
    int iRet = 0;

    if( CMainCtrl::m_pstMain->m_iNow >= this->m_petData._iNextCDTime )
    {
        CT_ERROR(("user:%u Not need consume gold to clear cd time in pet explore", _uiGID));
        return ERROR_NOT_NEED_CLEAR_PET_CDTIME;
    }

    int iLeftSec = this->m_petData._iNextCDTime - CMainCtrl::m_pstMain->m_iNow;
    int iNeedGold = 0;
    iRet = CMainCtrl::m_pstMain->m_stCommConfigLoader.GetCoolingPrice(PET_EXPLORE_COOLID, iLeftSec, iNeedGold);
    if( iNeedGold<=0 )
    {
        CT_ERROR(("user:%u Not gold to clear cd time in cool config file", _uiGID));
        return ERROR_NOT_CLEAR_PET_CDTIME_CONFIG;
    }

    //检查金币是否足够
    int iIndex = CMainCtrl::m_pstMain->m_stPlayerBaseInfoHash.HashFind(this->GetUserGid());
    CPlayerBaseInfo& stPlayerBaseInfo = CMainCtrl::m_pstMain->m_stPlayerBaseInfoHash[iIndex];
    if( iNeedGold > stPlayerBaseInfo._iGold )
    {
        CT_ERROR(("user:%u Not enough gold to clear cd time in cool", _uiGID));
        return ERROR_PET_TRAIN_NOT_ENOUGH_GOLD;
    }

    iRet = CMainCtrl::m_pstMain->m_stItemMgr.SubGold(stPlayerBaseInfo, OSS_MONEY_MODULE_31, iNeedGold);
    CHECK_RETURN(iRet);

    this->m_petData._iNextCDTime = 0;

    m_bPetStatusChange = true;

    //更新
    this->UpdatePetStatus();

    //推送金币剩余信息
    CMainCtrl::m_pstMain->m_stNotifyMgr.Notify(_uiGID, NOTIFY_USER_MONEY);

    return iRet;
}

//查询剩余每天前三次金币培养100%暴击次数
int CUserPet::GetPetCritCountsNotUpdate()
{
    int iRet = 0;
    //查看是否在当天的
    if( !this->m_petData._sExploreCountInDay.IsSameDay(CMainCtrl::m_pstMain->m_iNow) )
    {
        //this->m_petData._iCurTime = iTmpCurTime; 
        this->m_petData._iNextCDTime = 0; 
        //this->m_petData._iExploreCountInDay = MAX_PET_EXPLORE_NUM;
        this->m_petData._iDailyCritNums = MAX_DAILY_CRIT_NUM;
        //重新生成随机探险事件id列表
        iRet = ShuffleExploreEventList();
        CHECK_RETURN(iRet);

        this->m_petData._sExploreCountInDay._stData = MAX_PET_EXPLORE_NUM;
        this->m_petData._sExploreCountInDay._iLastUpdateTime = CMainCtrl::m_pstMain->m_iNow;

        m_bPetStatusChange = true;
    }

    return this->m_petData._iDailyCritNums;
}

//查询剩余每天前三次金币培养100%暴击次数
int CUserPet::GetPetCritCounts()
{
    int iRet = 0;
    //查看是否在当天的
    if( !this->m_petData._sExploreCountInDay.IsSameDay(CMainCtrl::m_pstMain->m_iNow) )
    {
        //this->m_petData._iCurTime = iTmpCurTime; 
        this->m_petData._iNextCDTime = 0; 
        //this->m_petData._iExploreCountInDay = MAX_PET_EXPLORE_NUM;
        this->m_petData._iDailyCritNums = MAX_DAILY_CRIT_NUM;
        //重新生成随机探险事件id列表
        iRet = ShuffleExploreEventList();
        CHECK_RETURN(iRet);

        this->m_petData._sExploreCountInDay._stData = MAX_PET_EXPLORE_NUM;
        this->m_petData._sExploreCountInDay._iLastUpdateTime = CMainCtrl::m_pstMain->m_iNow;

        m_bPetStatusChange = true;
    }

    //更新
    this->UpdatePetStatus();

    return this->m_petData._iDailyCritNums;
}

int CUserPet::PetChangeStyle(int iPetNewStyle)
{
    if( iPetNewStyle==this->m_petData._iPetStyle )
    {
        return ERROR_PET_SAME_STYLE;
    }

    if (iPetNewStyle > this->m_petData._iPetMaxCanUseStyle)
    {
        return ERROR_PET_STYLE_NEED_ENABLE;
    }

    this->m_petData._iPetStyle = iPetNewStyle;

    m_bPetStatusChange = true;
    //更新
    this->UpdatePetStatus();

    return 0;
}

int CUserPet::PetEnableNewStyle(int iPetNewStyle)
{
    int iRet = 0;

    if (this->m_petData._iPetMaxCanUseStyle >= iPetNewStyle)
    {
        return ERROR_PET_STYLE_HAS_ENABLED;
    }

    if (iPetNewStyle != this->m_petData._iPetMaxCanUseStyle + 1)
    {
        return ERROR_PET_STYLE;  //宠物形态需要按顺序激活
    }

    //检查金币是否足够
    int iIndex = CMainCtrl::m_pstMain->m_stPlayerBaseInfoHash.HashFind(this->GetUserGid());
    if (iIndex < 0)
    {
        return RET_SYS_ERROR;
    }

    CPlayerBaseInfo& stPlayerBaseInfo = CMainCtrl::m_pstMain->m_stPlayerBaseInfoHash[iIndex];
    if( PET_ENABLE_NEW_STYLE_NEED_GOLD > stPlayerBaseInfo._iGold )
    {
        return ERROR_GOLD_LESS;
    }

    iRet = CMainCtrl::m_pstMain->m_stItemMgr.SubGold(stPlayerBaseInfo, OSS_MONEY_MODULE_50, PET_ENABLE_NEW_STYLE_NEED_GOLD);
    CHECK_RETURN(iRet);
    CMainCtrl::m_pstMain->m_stNotifyMgr.Notify(this->GetUserGid(), NOTIFY_USER_MONEY, 0);

    this->m_petData._iPetMaxCanUseStyle = iPetNewStyle;
    PetChangeStyle(iPetNewStyle);

    //跑马灯
    MsgTips stTips;
    stTips.set_type(1072);
    stTips.add_tip_argument(CMainCtrl::m_pstMain->m_stRoleMgr.GetRoleName(GetUserGid()));
    CMainCtrl::m_pstMain->SendOnlineTips(stTips);

    return 0;
}

void CUserPet::SetUserGid(unsigned int uiGid)
{
		this->_uiGID = uiGid;
}

unsigned int CUserPet::GetUserGid() const
{
	return this->_uiGID;
}

//获取宠物战斗力
int CUserPet::GetPetLevelStarFruit(int & iLevel, int& iStar, int& iFruitNum)
{
    iLevel  = this->m_petData._iPetLevel;
    iStar   = this->m_petData._iPetStar;
    iFruitNum = this->m_petData._iPetFruit;

    return 0;
}

/*
 *  形态id  属性    属性id
 *  猫头鹰  1   魔攻    9
 *  猫  2   魔防    10
 *  仓鼠    3   物攻    7
 *  狗  4   物防    8
 *  最新修改为只有两种形态，猫对应物攻
 *  猫  2   物防    8
 *
 * */
int CUserPet::GetPetAttrs(
                        CPetLevelConfigData& stLevelConfigData, 
                        CPetStarConfigData& stStarConfigData, 
                        CPlayerAttr& astPetAttrs)
{
    int iRet = 0;

    //星级需要考虑增益能力
    //增加星级属性
    /*
    if( this->m_petData._iPetStyle==PET_STATUS_TYPE_OWL )//猫头鹰, 最新修改，猫头鹰加魔攻物攻
    {
        astPetAttrs._aiAttr[EXT_ATTR_MAG_ATK] += (stStarConfigData._iMagicAttack * (100+this->m_petData._iPetFruit))/100;
        astPetAttrs._aiAttr[EXT_ATTR_PHY_ATK] += (stStarConfigData._iPhyAttack * (100+this->m_petData._iPetFruit))/100;
    }
    else if( this->m_petData._iPetStyle==PET_STATUS_TYPE_CAT)//猫,最新修改，猫加魔防物防
    {
        astPetAttrs._aiAttr[EXT_ATTR_MAG_DEF] += (stStarConfigData._iMagicDefend * (100+this->m_petData._iPetFruit))/100;
        astPetAttrs._aiAttr[EXT_ATTR_PHY_DEF] += (stStarConfigData._iPhyDefend * (100+this->m_petData._iPetFruit))/100;
    }
    else if( this->m_petData._iPetStyle==PET_STATUS_TYPE_HAMSTER)//仓鼠
    {
        astPetAttrs._aiAttr[EXT_ATTR_PHY_ATK] += (stStarConfigData._iPhyAttack * (100+this->m_petData._iPetFruit))/100;
    }
    else if( this->m_petData._iPetStyle==PET_STATUS_TYPE_DOG)//狗
    {
        astPetAttrs._aiAttr[EXT_ATTR_PHY_DEF] += (stStarConfigData._iPhyDefend * (100+this->m_petData._iPetFruit))/100;
    }
    */

    if (this->m_petData._iPetMaxCanUseStyle >= PET_STATUS_TYPE_OWL)
    {
        astPetAttrs._aiAttr[EXT_ATTR_MAG_ATK] += (stStarConfigData._iMagicAttack * (100+this->m_petData._iPetFruit))/100;
        astPetAttrs._aiAttr[EXT_ATTR_PHY_ATK] += (stStarConfigData._iPhyAttack * (100+this->m_petData._iPetFruit))/100;
    }

    if (this->m_petData._iPetMaxCanUseStyle >= PET_STATUS_TYPE_CAT)
    {
        astPetAttrs._aiAttr[EXT_ATTR_MAG_DEF] += (stStarConfigData._iMagicDefend * (100+this->m_petData._iPetFruit))/100;
        astPetAttrs._aiAttr[EXT_ATTR_PHY_DEF] += (stStarConfigData._iPhyDefend * (100+this->m_petData._iPetFruit))/100;
    }

    //增加等阶属性
    for( int i=0; i<stLevelConfigData._aPetLevelAttrs.Size(); ++i )
    {
        astPetAttrs._aiAttr[stLevelConfigData._aPetLevelAttrs[i].iAttrId] = stLevelConfigData._aPetLevelAttrs[i].iAttrValue;
    }

    return iRet;
}


int CUserPet::UpdatePetStatus()
{
    int iRet = 0;

    if( this->m_bPetStatusChange )
    {
        int iIndex = CMainCtrl::m_pstMain->m_stPlayerBaseInfoHash.HashFind(this->GetUserGid());
        if (iIndex < 0)
        {
            CT_ERROR(("user %u not in hash", this->GetUserGid()));
            return -1;
        }
        CPlayerBaseInfo& stPlayerBaseInfo = CMainCtrl::m_pstMain->m_stPlayerBaseInfoHash[iIndex];

        iRet = this->GetData( stPlayerBaseInfo._stUserPetData );
        CHECK_RETURN(iRet);

        //保存数据
        CVarObjectKey stKey;
        stKey.m_chDataType = DT_PLAYER_BASE_INFO;
        stKey.m_u64ID = stPlayerBaseInfo._uiGID;
        CMainCtrl::m_pstMain->UpdateData(stKey, stPlayerBaseInfo, VOP_UPDATE);

        //下发新的宠物数据
        iRet = UpdatePetInfo2Front();
        CHECK_RETURN(iRet);
    }

    this->m_bPetStatusChange = false;

    return 0;
}

int CUserPet::UpdatePetInfo2Front()
{
    CMainCtrl::m_pstMain->m_stNotifyMgr.Notify(GetUserGid(), NOTIFY_PET_INFO);

    return RET_OK;
}

int CUserPet::GetPetFrontID()
{
    return m_petData._iPetStyle * 100 + m_petData._iPetLevel;
}

void CUserPet::GetPetBriefInfo(MsgPetBriefInfo& stMsgPetBriefInfo)
{
    if (!PetIsActive())
    {
        return;
    }

    stMsgPetBriefInfo.set_id(GetPetFrontID());
    stMsgPetBriefInfo.set_name(m_petData._sPetName.Get());
}

//是否有果实未领取, yes:true, no:false
bool CUserPet::HasFruitNotRecv()
{
    return this->m_petData._iIsRecvFruit==CONST_PET_HAS_FRUIT_NOT_RECV ? true:false;
}

